﻿using System;
using System.Collections.Generic;
using System.Text;
using Kiiro.Common.Interfaces;
using Kiiro.Common.Utility;

namespace Kiiro.Common.Entities
{
    [Serializable]
    public abstract class BaseEntity : IEntity, IPermissions
    {
        #region Private Properties

        private int id;

        private EditType editType = EditType.Created;
        private List<ValidationMessage> editTypeMessage = new List<ValidationMessage> ( );

        private Guid siteCollectionId = default ( Guid );
        private List<ValidationMessage> siteCollectionIdMessage = new List<ValidationMessage> ( );

        private string serverRelativeUrl;
        private List<ValidationMessage> serverRelativeUrlMessage = new List<ValidationMessage> ( );

        private string title;
        private List<ValidationMessage> titleMessage = new List<ValidationMessage> ( );

        private string description;
        private List<ValidationMessage> descriptionMessage = new List<ValidationMessage> ( );

        private bool isNew;
        private List<ValidationMessage> isNewMessage = new List<ValidationMessage> ( );

        private DateTime createdDate = DateTime.Now;
        private List<ValidationMessage> createdDateMessage = new List<ValidationMessage> ( );

        private User createdBy;
        private List<ValidationMessage> createdByMessage = new List<ValidationMessage> ( );

        private DateTime modifiedDate = DateTime.Now;
        private List<ValidationMessage> modifiedDateMessage = new List<ValidationMessage> ( );

        private User modifiedBy;
        private List<ValidationMessage> modifiedByMessage = new List<ValidationMessage> ( );

        private Dictionary<string, string> customFieldNamesAndValues;
        private List<ValidationMessage> customFieldNamesAndValuesMessage = new List<ValidationMessage> ( );

        private List<Attachment> attachmentList = new List<Attachment> ( );
        private List<ValidationMessage> attachmentListMessage = new List<ValidationMessage> ( ); 

        #endregion // Private Properties

        #region Public Properties

        public int Id
        {
            get { return id; }
            set
            {
                if ( id != value )
                {
                    id = value;
                    UpdateEntity ( );
                }
            }
        }

        public EditType EditType
        {
            get { return editType; }
            set
            {
                if ( editType != value )
                {
                    editType = value;
                    //UpdateEntity ( );
                }
            }
        }
        public List<ValidationMessage> EditTypeMessage
        {
            get { return editTypeMessage; }
            set
            {
                if ( editTypeMessage != value )
                {
                    editTypeMessage = value;
                    UpdateEntity ( );
                }
            }
        }

        public Guid SiteCollectionId
        {
            get { return siteCollectionId; }
            set
            {
                if ( siteCollectionId != value )
                {
                    siteCollectionId = value;
                    UpdateEntity ( );
                }
            }
        }
        public List<ValidationMessage> SiteCollectionIdMessage
        {
            get { return siteCollectionIdMessage; }
            set
            {
                if ( siteCollectionIdMessage != value )
                {
                    siteCollectionIdMessage = value;
                    UpdateEntity ( );
                }
            }
        }

        public string ServerRelativeUrl
        {
            get { return serverRelativeUrl; }
            set
            {
                if ( serverRelativeUrl != value )
                {
                    serverRelativeUrl = value;
                    UpdateEntity ( );
                }
            }
        }
        public List<ValidationMessage> ServerRelativeUrlMessage
        {
            get { return serverRelativeUrlMessage; }
            set
            {
                if ( serverRelativeUrlMessage != value )
                {
                    serverRelativeUrlMessage = value;
                    UpdateEntity ( );
                }
            }
        }

        public string Title
        {
            get { return title; }
            set
            {
                if ( title != value )
                {
                    title = value;
                    UpdateEntity ( );
                }
            }
        }
        public List<ValidationMessage> TitleMessage
        {
            get { return titleMessage; }
            set
            {
                if ( titleMessage != value )
                {
                    titleMessage = value;
                    UpdateEntity ( );
                }
            }
        }

        public string Description
        {
            get { return description; }
            set
            {
                if ( description != value )
                {
                    description = value;
                    UpdateEntity ( );
                }
            }
        }
        public List<ValidationMessage> DescriptionMessage
        {
            get { return descriptionMessage; }
            set
            {
                if ( descriptionMessage != value )
                {
                    descriptionMessage = value;
                    UpdateEntity ( );
                }
            }
        }

        public bool IsNew
        {
            get { return isNew; }
            set
            {
                if ( isNew != value )
                {
                    isNew = value;
                    UpdateEntity ( );
                }
            }
        }
        public List<ValidationMessage> IsNewMessage
        {
            get { return isNewMessage; }
            set
            {
                if ( isNewMessage != value )
                {
                    isNewMessage = value;
                    UpdateEntity ( );
                }
            }
        }

        public DateTime CreatedDate
        {
            get { return createdDate; }
            set
            {
                if ( createdDate != value )
                {
                    createdDate = value;
                    UpdateEntity ( );
                }
            }
        }
        public List<ValidationMessage> CreatedDateMessage
        {
            get { return createdDateMessage; }
            set
            {
                if ( createdDateMessage != value )
                {
                    createdDateMessage = value;
                    UpdateEntity ( );
                }
            }
        }

        public User CreatedBy
        {
            get { return createdBy; }
            set
            {
                if ( createdBy != value )
                {
                    createdBy = value;
                    UpdateEntity ( );
                }
            }
        }
        public List<ValidationMessage> CreatedByMessage
        {
            get { return createdByMessage; }
            set
            {
                if ( createdByMessage != value )
                {
                    createdByMessage = value;
                    UpdateEntity ( );
                }
            }
        }

        public DateTime ModifiedDate
        {
            get { return modifiedDate; }
            set
            {
                if ( modifiedDate != value )
                {
                    modifiedDate = value;
                    UpdateEntity ( );
                }
            }
        }
        public List<ValidationMessage> ModifiedDateMessage
        {
            get { return modifiedDateMessage; }
            set
            {
                if ( modifiedDateMessage != value )
                {
                    modifiedDateMessage = value;
                    UpdateEntity ( );
                }
            }
        }

        public User ModifiedBy
        {
            get { return modifiedBy; }
            set
            {
                if ( modifiedBy != value )
                {
                    modifiedBy = value;
                    UpdateEntity ( );
                }
            }
        }
        public List<ValidationMessage> ModifiedByMessage
        {
            get { return modifiedByMessage; }
            set
            {
                if ( modifiedByMessage != value )
                {
                    modifiedByMessage = value;
                    UpdateEntity ( );
                }
            }
        }

        public Dictionary<string, string> CustomFieldNamesAndValues
        {
            get { return customFieldNamesAndValues; }
            set
            {
                if ( customFieldNamesAndValues != value )
                {
                    customFieldNamesAndValues = value;
                    UpdateEntity ( );
                }
            }
        }

        public List<ValidationMessage> CustomFieldNamesAndValuesMessage
        {
            get { return customFieldNamesAndValuesMessage; }
            set
            {
                if ( customFieldNamesAndValuesMessage != value )
                {
                    customFieldNamesAndValuesMessage = value;
                    UpdateEntity ( );
                }
            }
        }

        public List<Attachment> AttachmentList
        {
            get { return attachmentList; }
            set
            {
                if ( attachmentList != value )
                {
                    attachmentList = value;
                    UpdateEntity ( );
                }
            }
        }

        public List<ValidationMessage> AttachmentListMessage
        {
            get { return attachmentListMessage; }
            set
            {
                if ( attachmentListMessage != value )
                {
                    attachmentListMessage = value;
                    UpdateEntity ( );
                }
            }
        }

        #endregion // Public Properties

        protected void UpdateEntity ( )
        {
            if ( EditType == EditType.Unchanged )
            {
                EditType = EditType.Updated;
            }
        }

        #region IEntity Members

        public bool IsValid ( )
        {
            return AllValidationErrors ( ).Count == 0;
        }

        public List<ValidationMessage> AllValidationErrors ( )
        {
            List<ValidationMessage> allErrors = new List<ValidationMessage> ( );

            allErrors.AddRange ( EditTypeMessage );
            allErrors.AddRange ( SiteCollectionIdMessage );
            allErrors.AddRange ( ServerRelativeUrlMessage );
            allErrors.AddRange ( TitleMessage );
            allErrors.AddRange ( DescriptionMessage );
            allErrors.AddRange ( IsNewMessage );
            allErrors.AddRange ( CreatedByMessage );
            allErrors.AddRange ( CreatedDateMessage );
            allErrors.AddRange ( ModifiedByMessage );
            allErrors.AddRange ( ModifiedDateMessage );
            allErrors.AddRange ( AttachmentListMessage );

            return allErrors;
        }

        public void ClearValidationMessages ( )
        {
            EditTypeMessage.Clear ( );
            SiteCollectionIdMessage.Clear ( );
            ServerRelativeUrlMessage.Clear ( );
            TitleMessage.Clear ( );
            DescriptionMessage.Clear ( );
            IsNewMessage.Clear ( );
            CreatedByMessage.Clear ( );
            CreatedDateMessage.Clear ( );
            ModifiedByMessage.Clear ( );
            ModifiedDateMessage.Clear ( );
            AttachmentListMessage.Clear ( );
        }

        #endregion // IEntity Members

        #region IPermissions Members

        private List<bool> permissionBitsSetup = new List<bool> ( );
        /// <summary>
        /// Setup: C = 0, R = 1, U = 2, D = 3
        /// </summary>
        public List<bool> PermissionBitsSetup
        {
            get { return this.permissionBitsSetup; }
            set
            {
                List<bool> bits = new List<bool> ( );

                if ( this.permissionBitsSetup.Count > 0 )
                    bits = this.permissionBitsSetup;
                else
                    bits = value;

                this.permissionBitsSetup = bits;
            }
        }

        private List<bool> permissionBitsUser = new List<bool> ( );
        /// <summary>
        /// Users: C = 0, R = 1, U = 2, D = 3
        /// </summary>
        public List<bool> PermissionBitsUsers
        {
            get { return this.permissionBitsUser; }
            set
            {
                List<bool> bits = new List<bool> ( );

                if ( this.permissionBitsUser.Count > 0 )
                    bits = this.permissionBitsUser;
                else
                    bits = value;

                this.permissionBitsUser = bits;
            }
        }

        private List<bool> permissionBitsProjects = new List<bool> ( );
        /// <summary>
        /// Projects: C = 0, R = 1, U = 2, D = 3
        /// </summary>
        public List<bool> PermissionBitsProjects
        {
            get { return this.permissionBitsProjects; }
            set
            {
                List<bool> bits = new List<bool> ( );

                if ( this.permissionBitsProjects.Count > 0 )
                    bits = this.permissionBitsProjects;
                else
                    bits = value;

                this.permissionBitsProjects = bits;
            }
        }

        private List<bool> permissionBitsActivity = new List<bool> ( );
        /// <summary>
        /// Activity: C = 0, R = 1, U = 2, D = 3
        /// </summary>
        public List<bool> PermissionBitsActivity
        {
            get { return this.permissionBitsActivity; }
            set
            {
                List<bool> bits = new List<bool> ( );

                if ( this.permissionBitsActivity.Count > 0 )
                    bits = this.permissionBitsActivity;
                else
                    bits = value;

                this.permissionBitsActivity = bits;
            }
        }

        private List<bool> permissionBitsTeams = new List<bool> ( );
        /// <summary>
        /// Teams: C = 0, R = 1, U = 2, D = 3
        /// </summary>
        public List<bool> PermissionBitsTeams
        {
            get { return this.permissionBitsTeams; }
            set
            {
                List<bool> bits = new List<bool> ( );

                if ( this.permissionBitsTeams.Count > 0 )
                    bits = this.permissionBitsTeams;
                else
                    bits = value;

                this.permissionBitsTeams = bits;
            }
        }

        private List<bool> permissionBitsWork = new List<bool> ( );
        /// <summary>
        /// Work: C = 0, R = 1, U = 2, D = 3
        /// </summary>
        public List<bool> PermissionBitsWork
        {
            get { return this.permissionBitsWork; }
            set
            {
                List<bool> bits = new List<bool> ( );

                if ( this.permissionBitsWork.Count > 0 )
                    bits = this.permissionBitsWork;
                else
                    bits = value;

                this.permissionBitsWork = bits;
            }
        }

        private List<bool> permissionBitsDiscussions = new List<bool> ( );
        /// <summary>
        /// Discussions: C = 0, R = 1, U = 2, D = 3
        /// </summary>
        public List<bool> PermissionBitsDiscussions
        {
            get { return this.permissionBitsDiscussions; }
            set
            {
                List<bool> bits = new List<bool> ( );

                if ( this.permissionBitsDiscussions.Count > 0 )
                    bits = this.permissionBitsDiscussions;
                else
                    bits = value;

                this.permissionBitsDiscussions = bits;
            }
        }

        private List<bool> permissionBitsDocuments = new List<bool> ( );
        /// <summary>
        /// Documents: C = 0, R = 1, U = 2, D = 3
        /// </summary>
        public List<bool> PermissionBitsDocuments
        {
            get { return this.permissionBitsDocuments; }
            set
            {
                List<bool> bits = new List<bool> ( );

                if ( this.permissionBitsDocuments.Count > 0 )
                    bits = this.permissionBitsDocuments;
                else
                    bits = value;

                this.permissionBitsDocuments = bits;
            }
        }

        private List<bool> permissionBitsLists = new List<bool> ( );
        /// <summary>
        /// Lists: C = 0, R = 1, U = 2, D = 3
        /// </summary>
        public List<bool> PermissionBitsLists
        {
            get { return this.permissionBitsLists; }
            set
            {
                List<bool> bits = new List<bool> ( );

                if ( this.permissionBitsLists.Count > 0 )
                    bits = this.permissionBitsLists;
                else
                    bits = value;

                this.permissionBitsLists = bits;
            }
        }

        private List<bool> permissionBitsProjectPlanFile = new List<bool> ( );
        /// <summary>
        /// Project Plan File: C = 0, R = 1, U = 2, D = 3
        /// </summary>
        public List<bool> PermissionBitsProjectPlanFile
        {
            get { return this.permissionBitsProjectPlanFile; }
            set
            {
                List<bool> bits = new List<bool> ( );

                if ( this.permissionBitsProjectPlanFile.Count > 0 )
                    bits = this.permissionBitsProjectPlanFile;
                else
                    bits = value;

                this.permissionBitsProjectPlanFile = bits;
            }
        }

        private List<string> permissionErrorMessages = new List<string> ( );
        /// <summary>
        /// Error messages associated with Permsissions validation
        /// </summary>
        public List<string> PermissionErrorMessages
        {
            get { return this.permissionErrorMessages; }
            set
            {
                List<string> errors = new List<string> ( );

                if ( this.permissionErrorMessages.Count > 0 )
                    errors = this.permissionErrorMessages;
                else
                    errors = value;

                this.permissionErrorMessages = errors;
            }
        }

        private bool keyIsValid = false;
        /// <summary>
        /// Is the License Key Valid?
        /// </summary>
        public bool LicenseKeyIsValid
        {
            get { return this.keyIsValid && this.LicenseKeyErrorMessages.Count == 0; }
            set { this.keyIsValid = value; }
        }

        private List<bool> keyBits = new List<bool> ( );
        /// <summary>
        /// License Key: Key Expired = 0, Project Limit = 1, User Limit = 2
        /// </summary>
        public List<bool> LicenseKeyBits
        {
            get { return this.keyBits; }
            set
            {
                List<bool> bits = new List<bool> ( );

                if ( this.keyBits.Count > 0 )
                    bits = this.keyBits;
                else
                    bits = value;

                this.keyBits = bits;
            }
        }

        private List<string> keyErrorMessages = new List<string> ( );
        /// <summary>
        /// Error Messages associated with validation the License Key
        /// </summary>
        public List<string> LicenseKeyErrorMessages
        {
            get { return this.keyErrorMessages; }
        }

        /// <summary>
        /// Not used
        /// </summary>
        void IPermissions.GetPermissionBitsForPage ( )
        {
            throw new NotImplementedException ( );
        }

        /// <summary>
        /// Not Used
        /// </summary>
        bool IPermissions.DoesPageHavePermissionsSet
        {
            get { throw new NotImplementedException ( ); }
        }

        // Special Case Helpers

        /// <summary>
        /// User Id of User being viewed (base.ItemId)
        /// </summary>
        public int UserId
        {
            get { return this.Id; }
        }

        private int authorId = 0;
        /// <summary>
        /// Discussion Author's Midori Id
        /// </summary>
        public int AuthorId
        {
            get { return this.CreatedBy != null && this.CreatedBy.Id > 0 ? this.CreatedBy.Id : authorId; }
            set { this.authorId = value; }
        }

        // Special Cases

        private bool canUserUpdateThemselves = false;
        /// <summary>
        /// Can the Current User Update the User being Displayed?
        /// </summary>
        public bool CanUserUpdateThemselves
        {
            get { return this.canUserUpdateThemselves; }
            set { this.canUserUpdateThemselves = value; }
        }

        private bool canTeamMemberUpdateWork = false;
        /// <summary>
        /// Can Team Member Update Work (checks if from Project Plan)?
        /// </summary>
        public bool CanTeamMemberUpdateWork
        {
            get { return this.canTeamMemberUpdateWork; }
            set { this.canTeamMemberUpdateWork = value; }
        }

        private bool canTeamMemberUpdateDiscussion = false;
        /// <summary>
        /// Can a Team Member/Project Manager Update/Delete Discussion?
        /// </summary>
        public bool CanTeamMemberUpdateDiscussion
        {
            get { return this.canTeamMemberUpdateDiscussion; }
            set { this.canTeamMemberUpdateDiscussion = value; }
        }

        #endregion // IPermissions Members
    }
}

/*************************************************************************
 * 
 * $Log: /Internal Projects/Kiiro/Kiiro.Common/Entities/BaseEntity.cs $
 * 
 * 4     17/08/09 10:38a Camerons
 * Added check-in comments section
 * 
 ************************************************************************/